﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using FreeImageAPI;
using System.Windows.Forms;
using FreeImageAPI.Plugins;
using System.Drawing;
using FreeImageAPI.Metadata;

namespace mogco
{
    class ImageWorker
    {
        private FreeImageBitmap FBitmap;

        // Methods

        public void ReturnExif()
        {
        }


        private FreeImageBitmap LoadImage(string path)
        {
            FreeImageBitmap fib;
            FreeImagePlugin plug;
            if (!FreeImage.IsAvailable())
            {
                Logger.txtLogger.WriteMessage("FreeImage missing");
                return null;
            }
            try
            {
                fib = new FreeImageBitmap(path);
                plug = PluginRepository.Plugin(fib.ImageFormat);
            }
            catch (Exception e)
            {
                Logger.txtLogger.WriteMessage("Can't load bitmap: " + path + " " + e.ToString());
                return null;
            }

            if (fib == null || fib.IsDisposed)
            {
                MessageBox.Show("Can't use bitmap");
                return null;
            }

            if (fib.ImageType != FREE_IMAGE_TYPE.FIT_BITMAP)
            {
                if (!fib.ConvertType(FREE_IMAGE_TYPE.FIT_BITMAP, true))
                {
                    Logger.txtLogger.WriteMessage("Error converting bitmap to standard type.");
                    return null;
                }
            }

            if ((FBitmap != null) && !object.ReferenceEquals(FBitmap, fib))
            {
                FBitmap.Dispose();
            }

            return fib;
        }

        public MDM_EXIF_EXIF GetEXIF(string path)
        {
            FIBITMAP dib = FreeImage.LoadEx(path);
           // MDM_EXIF_MAIN exif = new MDM_EXIF_MAIN(dib);
            MDM_EXIF_EXIF exif = new MDM_EXIF_EXIF(dib);
            FreeImage.UnloadEx(ref dib);
            return exif;
        }

        public BITMAPINFOHEADER GetBitmapProps(string path)
        {
            BITMAPINFOHEADER header = new BITMAPINFOHEADER();
            try
            {
                FIBITMAP dib = FreeImage.LoadEx(path);
                header = FreeImage.GetInfoHeaderEx(dib);
                FreeImage.UnloadEx(ref dib);
            }
            catch (Exception e)
            {
                Logger.txtLogger.WriteMessage("Can't get bitmap properties" + e.ToString());
            }
            return header;
        }

        public void ConvertImage(string path, string savepath)
        {
                FIBITMAP dib, result;
                dib = FreeImage.LoadEx(path, FREE_IMAGE_LOAD_FLAGS.DEFAULT);
                if (dib.IsNull)
                {
                    FreeImage.Unload(dib);
                    throw new Exception("Cannot load image. FIBITMAP is null");
                }

                // сохранить switch формат в настройках

                // calc aspect ratio
                uint height = FreeImage.GetHeight(dib);
                uint width = FreeImage.GetWidth(dib);
                float aspratio = (float)width / height;
                int new_width = 0;
                int new_height = 0;
                if (height > Settings.xml.Resolution.Y || width > Settings.xml.Resolution.X)
                {
                    if (height >= width)
                    {
                        new_height = Settings.xml.Resolution.Y;
                        new_width = (int)(Settings.xml.Resolution.Y * aspratio);
                    }
                    else
                    {
                        new_width = Settings.xml.Resolution.X;
                        new_height = (int)(Settings.xml.Resolution.X / aspratio);
                    }
                    result = FreeImage.Rescale(dib, new_width, new_height, FREE_IMAGE_FILTER.FILTER_CATMULLROM);
                }
                else
                {
                    result = dib;
                }
                // можно, конечно, флаги поставить, но впадло писать еще одну обертку для Save 
                switch (Settings.xml.SaveFormat)
                {
                    case mogco.Structs.Structs.PictureExtensions.JPG:
                        if (!(FreeImage.SaveCustomQuality(ref result,
                            savepath,
                            FREE_IMAGE_FORMAT.FIF_JPEG,
                            Settings.xml.JPGQuality,
                            FREE_IMAGE_COLOR_DEPTH.FICD_AUTO,
                            true)))
                        {
                            throw new Exception("Image was not saved");
                        }
                        break;
                    case mogco.Structs.Structs.PictureExtensions.PNG:
                        if (!(FreeImage.SaveEx(ref result,
                            savepath,
                            FREE_IMAGE_FORMAT.FIF_PNG,
                            FREE_IMAGE_SAVE_FLAGS.PNG_Z_DEFAULT_COMPRESSION,
                            FREE_IMAGE_COLOR_DEPTH.FICD_AUTO,
                            true)))
                        {
                            throw new Exception("Image was not saved");
                        }
                        break;
                    default:
                        throw new Exception("Error. Wrong save format.");
                }
                FreeImage.UnloadEx(ref result);
                FreeImage.UnloadEx(ref dib);
        }

        public Bitmap GetImage(string path)
        {
            FBitmap = this.LoadImage(path);
            return (Bitmap)(FBitmap);
        }

        #region makeThumbnails
        public Bitmap GetThumbnails(string path, Size size)
        {
            FBitmap = LoadImage(path);
            Bitmap result;
            if (FBitmap != null)
            {
                result = (Bitmap)FBitmap.GetThumbnailImage(size.Height, false);
                FBitmap.Dispose();
                return result;
            }
            else
                return null;
        }

        public Bitmap GetThumbnails(Image image, Size size)
        {
            FBitmap = (FreeImageBitmap)image;
            if (FBitmap != null)
            {
                FBitmap = FBitmap.GetThumbnailImage(size.Height, false);
                return (Bitmap)(FBitmap);
            }
            else
                return null;
        }
        #endregion

    }
}
